home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / sw / hud.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  15.9 KB  |  582 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include "sw.h"
  19. #include "extern.h"
  20. #include "hud.h"
  21. #include "main.h"
  22. #include "explode.h"
  23. #include "ship.h"
  24. #include <Inventor/actions/SoGLRenderAction.h>
  25. #include <Inventor/events/SoMouseButtonEvent.h>
  26. #include <Inventor/events/SoLocation2Event.h>
  27. #include <Inventor/actions/SoAction.h>
  28. #include <Inventor/SoEventCallback.h>
  29. #include <Inventor/nodes/SoCallback.h>
  30. #include <gl/gl.h>
  31. #include <gl/glws.h>
  32.  
  33. #define    SELFEXPLODENUM    4
  34.  
  35. struct ObjectNumber {
  36.   public:
  37.     int            player;
  38.     int            subobject;
  39.     float        z;
  40.     float        t;
  41. };
  42.  
  43. static ObjectNumber    explosionList[MAXPLAYERS * (MAXMISSILES + 1)];
  44. static short        selfExplodePos[SELFEXPLODENUM][2];
  45. static int        hudColorState;
  46. static int        hudFrameNumber = -1;
  47.  
  48. static void        drawExplosions()
  49. {
  50.   // get list of explosions
  51.   short numExplosions = 0;
  52.   for (int i = 0; i < MAXPLAYERS; i++) {
  53.     ShipObject* s = getPlayer(i);
  54.     if (!s || s->active() != ObjectActive) continue;
  55.     ShipInfo& si = s->shipInfo();
  56.     if (playerView[i][0].visible && playerView[i][0].exploding) {
  57.       explosionList[numExplosions].player = i;
  58.       explosionList[numExplosions].subobject = 0;
  59.       explosionList[numExplosions].z = playerView[i][0].lp[2];
  60.       explosionList[numExplosions].t = si.info.explodeTime;
  61.       numExplosions++;
  62.     }
  63.     for (int j = 0; j < MAXMISSILES; j++) {
  64.       if (si.missile[j].active != ObjectActive) continue;
  65.       if (playerView[i][j+1].visible && playerView[i][j+1].exploding) {
  66.     explosionList[numExplosions].player = i;
  67.     explosionList[numExplosions].subobject = j+1;
  68.     explosionList[numExplosions].z = playerView[i][j+1].lp[2];
  69.     explosionList[numExplosions].t = si.missile[j].explodeTime;
  70.     numExplosions++;
  71.       }
  72.     }
  73.   }
  74.   if (numExplosions == 0) return;        // nothing to draw
  75.  
  76.   // sort explosions back to front
  77.   ObjectNumber tmp;
  78.   for (i = 0; i < numExplosions-1; i++)
  79.     for (int j = 1; j < numExplosions-i; j++)
  80.       if (explosionList[j].z < explosionList[j-1].z) {
  81.     tmp = explosionList[j-1];
  82.     explosionList[j-1] = explosionList[j];
  83.     explosionList[j] = tmp;
  84.       }
  85.  
  86.   // draw explosions
  87.   ortho(-0.5, viewScreenSize()[0] - 0.5, -0.5, viewScreenSize()[1] - 0.5,
  88.                                 -1.0, 1.0);
  89.   zwritemask(0);
  90.   blendfunction(BF_SA, BF_MSA);
  91.   for (i = 0; i < numExplosions; i++) {
  92.     int p = explosionList[i].player, s = explosionList[i].subobject;
  93.     float z = (-playerView[p][s].lp[2] * (YONPLANE + HITHERPLANE) -
  94.                     2.0 * HITHERPLANE * YONPLANE) /
  95.         (-playerView[p][s].lp[2] * (YONPLANE - HITHERPLANE));
  96.     drawExplosion(playerView[p][s].p[0], playerView[p][s].p[1],
  97.             playerView[p][s].r, z, explosionList[i].t);
  98.   }
  99.   blendfunction(BF_ONE, BF_ZERO);
  100.   zwritemask(0xffffffff);
  101. }
  102.  
  103. static void        drawSelfExplosion()
  104. {
  105.   ortho(-0.5, viewScreenSize()[0] - 0.5, -0.5, viewScreenSize()[1] - 0.5,
  106.                                 -1.0, 1.0);
  107.   zwritemask(0);
  108.   blendfunction(BF_SA, BF_MSA);
  109.   for (int i = 0; i < SELFEXPLODENUM; i++)
  110.     drawExplosion(selfExplodePos[i][0], selfExplodePos[i][1],
  111.         viewScreenSize()[1], -0.999, myShip->explodeTime());
  112.   blendfunction(BF_ONE, BF_ZERO);
  113.   zwritemask(0xffffffff);
  114. }
  115.  
  116. static void        drawHud(void*)
  117. {
  118.   if (!isPaused() && frameNumber == hudFrameNumber)    // avoid extra redraws
  119.     return;
  120.   hudFrameNumber = frameNumber;
  121.  
  122.   // set up GL context
  123.   GLXwinset(display, view->getNormalWindow());
  124.   font(0);
  125.   short fh = (short)getheight() - (short)getdescender();
  126.  
  127.   // draw all explosions
  128.   drawExplosions();
  129.   if (myShip->exploding()) drawSelfExplosion();
  130.  
  131.   if (hudColorState != 0) {            // if want it drawn
  132.  
  133.   short cx = viewScreenSize()[0], cy = viewScreenSize()[1];
  134.   ortho2(-0.5, cx - 0.5, -0.5, cy - 0.5);
  135.  
  136.   // set HUD color
  137.   switch (hudColorState) {
  138.     case 1: cpack(0xff00ff00); break;
  139.     case 2: cpack(0xff008000); break;
  140.   }
  141.  
  142.   // draw center cross hair
  143.   cx >>= 1;
  144.   cy >>= 1;
  145.   short x = cx, y = cy;
  146.   sboxs(x - 10, y, x - 20, y);
  147.   sboxs(x + 10, y, x + 20, y);
  148.   sboxs(x, y - 10, x, y - 20);
  149.   sboxs(x, y + 10, x, y + 20);
  150.  
  151.   // draw tracking cross hairs
  152.   SbVec2s trackingPos;
  153.   getViewPosition(myShip->trackDirection(), trackingPos);
  154.   x = trackingPos[0];
  155.   y = trackingPos[1];
  156.   short v[2];
  157.   bgnclosedline();
  158.     v[0] = x + 12; v[1] = y + 12; v2s(v);
  159.     v[0] = x + 6; v[1] = y + 6; v2s(v);
  160.   endclosedline();
  161.   bgnclosedline();
  162.     v[0] = x + 12; v[1] = y - 12; v2s(v);
  163.     v[0] = x + 6; v[1] = y - 6; v2s(v);
  164.   endclosedline();
  165.   bgnclosedline();
  166.     v[0] = x - 12; v[1] = y - 12; v2s(v);
  167.     v[0] = x - 6; v[1] = y - 6; v2s(v);
  168.   endclosedline();
  169.   bgnclosedline();
  170.     v[0] = x - 12; v[1] = y + 12; v2s(v);
  171.     v[0] = x - 6; v[1] = y + 6; v2s(v);
  172.   endclosedline();
  173.  
  174.   // is fps display on then show fps
  175.   if (isFpsOn()) {
  176.     char buf[10];
  177.     sprintf(buf, "%d", getFps());
  178.     cmov2s(cx - 100, cy - 104 - fh);
  179.     charstr(buf);
  180.   }
  181.  
  182.   // get target info
  183.   int target = currentTarget();
  184.   ShipObject* tObj = (target == -1) ? NULL : getTarget(target);
  185.   float th, tp;
  186.   if (tObj) {
  187.     SbVec3f td = tObj->position();
  188.     td -= myShip->position();
  189.     th = atan2(td[2], td[0]) * 180.0 / M_PI;
  190.     if (th < 0.0) th += 360.0;
  191.     tp = asin(td[1] / td.length()) * 180.0 / M_PI;
  192.   }
  193.  
  194.   // draw heading and pitch meters
  195.   float    a;
  196.   short    am, ai;
  197.   char num[4];
  198.  
  199.   // draw heading meter
  200.   a = atan2(myShip->direction()[2], myShip->direction()[0]) * 180.0 / M_PI;
  201.   if (a < 0.0) a += 360.0;
  202.   am = (short)(a/30) - 1;
  203.   if (am < 0) am += 12;
  204.   pushviewport();
  205.   scrmask(cx - 100, cx + 100, cy + 105, cy + 130);
  206.   sboxs(cx, cy + 105, cx, cy + 110);
  207.   pushmatrix();
  208.     translate(cx - ((short)(a*3) % 90), cy + 110, 0.0);
  209.     for (short i = -90; i <= 180; i += 90) {    // tick marks
  210.       sboxs(i, 0, i, 5);
  211.       sboxs(i+30, 0, i+30, 3);
  212.       sboxs(i+60, 0, i+60, 3);
  213.     }
  214.     for (i = 0; i <= 3; i++) {            // degree labels
  215.       sprintf(num, "%d", ((am+i) * 30) % 360);
  216.       cmov2s(90 * i - (short)(strwidth(num) >> 1) - 90, 7);
  217.       charstr(num);
  218.     }
  219.  
  220.     // if there is a target draw it's heading as a diamond
  221.     if (target != -1) {
  222.       translate((short)(a*3) % 90, 0.0, 0.0);
  223.       short tx = short(3.0 * (th - a));
  224.       if (tx < 3 * -180) tx += 3 * 360;
  225.       else if (tx > 3 * 180) tx -= 3 * 360;
  226.       if (tx < 95) {                // draw left pointing arrow
  227.     bgnpolygon();
  228.       v[0] = (tx < -95) ? -95 : tx; v[1] = 10; v2s(v);
  229.       v[0] -= 5; v[1] = 5; v2s(v);
  230.       v[0] += 5; v[1] = 0; v2s(v);
  231.     endpolygon();
  232.       }
  233.       if (tx > -95) {                // draw right pointing arrow
  234.     bgnpolygon();
  235.       v[0] = (tx > 95) ? 95 : tx; v[1] = 0; v2s(v);
  236.       v[0] += 5; v[1] = 5; v2s(v);
  237.       v[0] -= 5; v[1] = 10; v2s(v);
  238.     endpolygon();
  239.       }
  240.     }
  241.   popmatrix();
  242.  
  243.   // draw pitch meter
  244.   a = asin(myShip->direction()[1]) * 180.0 / M_PI;
  245.   am = (short)(a/10);
  246.   scrmask(cx - 150, cx - 105, cy - 100, cy + 100);
  247.   sboxs(cx - 110, cy, cx - 105, cy);
  248.   pushmatrix();
  249.     translate(cx - 110, cy - ((short)(a*5) % 50), 0.0);
  250.     for (ai = am - 3, i = -150; i <= 100; ai++, i += 50) {
  251.       if (ai < -9 || ai > 9) continue;
  252.       sboxs(-5, i, 0, i);
  253.       if (ai == 9) continue;
  254.       sboxs(-3, i+10, 0, i+10);
  255.       sboxs(-3, i+20, 0, i+20);
  256.       sboxs(-3, i+30, 0, i+30);
  257.       sboxs(-3, i+40, 0, i+40);
  258.     }
  259.     for (ai = am - 2, i = -2; i <= 3; ai++, i++) {
  260.       if (ai < -9 || ai > 9) continue;
  261.       sprintf(num, "%d", ai * 10);
  262.       cmov2s(-7 - (short)strwidth(num), 50 * i - (fh >> 1));
  263.       charstr(num);
  264.     }
  265.  
  266.     // if there is a target draw it's heading as a diamond
  267.     if (target != -1) {
  268.       translate(0.0, (short)(a*5) % 50, 0.0);
  269.       short ty = short(5.0 * (tp - a));
  270.       if (ty < 5 * -90) ty += 5 * 180;
  271.       else if (ty > 5 * 90) ty -= 5 * 180;
  272.       if (ty < 95) {                // draw down pointing arrow
  273.     bgnpolygon();
  274.       v[0] = -10; v[1] = (ty < -95) ? -95 : ty; v2s(v);
  275.       v[0] = -5; v[1] -= 5; v2s(v);
  276.       v[0] = 0; v[1] += 5; v2s(v);
  277.     endpolygon();
  278.       }
  279.       if (ty > -95) {                // draw up pointing arrow
  280.     bgnpolygon();
  281.       v[0] = 0; v[1] = (ty > 95) ? 95 : ty; v2s(v);
  282.       v[0] = -5; v[1] += 5; v2s(v);
  283.       v[0] = -10; v[1] -= 5; v2s(v);
  284.     endpolygon();
  285.       }
  286.     }
  287.   popmatrix();
  288.   popviewport();
  289.  
  290.   // draw targeting boxes around all potential targets
  291.   SbVec3f ltd, td;
  292.   SbVec2s p;
  293.   for (int j = 1; j < MAXPLAYERS; j++) {
  294.     ShipObject* s = getPlayer(j);
  295.     if (!s) continue;
  296.     if (s->shipVisibility()) {
  297.       if (tObj == s) {
  298.     rects(playerView[j][0].p[0] - 12,
  299.         playerView[j][0].p[1] - 12,
  300.         playerView[j][0].p[0] + 12,
  301.         playerView[j][0].p[1] + 12);
  302.     rects(playerView[j][0].p[0] - 11,
  303.         playerView[j][0].p[1] - 11,
  304.         playerView[j][0].p[0] + 11,
  305.         playerView[j][0].p[1] + 11);
  306.       }
  307.       else {
  308.     rects(playerView[j][0].p[0] - 6,
  309.         playerView[j][0].p[1] - 6,
  310.         playerView[j][0].p[0] + 6,
  311.         playerView[j][0].p[1] + 6);
  312.     rects(playerView[j][0].p[0] - 5,
  313.         playerView[j][0].p[1] - 5,
  314.         playerView[j][0].p[0] + 5,
  315.         playerView[j][0].p[1] + 5);
  316.       }
  317.     }
  318.   }
  319.  
  320.   // draw missile lock diamond
  321.   if (missileLock.visible) {
  322.     v[0] = missileLock.p[0] + cx;
  323.     v[1] = missileLock.p[1] + cy;
  324.     bgnline();
  325.       v[1] -= missileLock.r; v2s(v);
  326.       v[0] += missileLock.r; v[1] += missileLock.r; v2s(v);
  327.       v[0] -= missileLock.r; v[1] += missileLock.r; v2s(v);
  328.       v[0] -= missileLock.r; v[1] -= missileLock.r; v2s(v);
  329.       v[0] += missileLock.r; v[1] -= missileLock.r; v2s(v);
  330.     endline();
  331.     bgnclosedline();
  332.       v[1] += 1; v2s(v);
  333.       v[0] += missileLock.r - 1; v[1] += missileLock.r - 1; v2s(v);
  334.       v[0] -= missileLock.r - 1; v[1] += missileLock.r - 1; v2s(v);
  335.       v[0] -= missileLock.r - 1; v[1] -= missileLock.r - 1; v2s(v);
  336.     endclosedline();
  337.   }
  338.  
  339.   // set HUD color for missile boxes
  340.   switch (hudColorState) {
  341.     case 1: cpack(0xff00c0ff); break;
  342.     case 2: cpack(0xff006080); break;
  343.   }
  344.  
  345.   // draw boxes around all missiles that aren't mine
  346.   for (j = 1; j < MAXPLAYERS; j++) {
  347.     ShipObject* s = getPlayer(j);
  348.     if (!s) continue;
  349.     for (int k = 0; k < MAXMISSILES; k++) {
  350.       if (s->missileVisibility(k)) {
  351.     rects(playerView[j][k+1].p[0] - 6,
  352.         playerView[j][k+1].p[1] - 6,
  353.         playerView[j][k+1].p[0] + 6,
  354.         playerView[j][k+1].p[1] + 6);
  355.     rects(playerView[j][k+1].p[0] - 5,
  356.         playerView[j][k+1].p[1] - 5,
  357.         playerView[j][k+1].p[0] + 5,
  358.         playerView[j][k+1].p[1] + 5);
  359.       }
  360.     }
  361.   }
  362.  
  363.   // set HUD color for team flag boxes
  364.   switch (hudColorState) {
  365.     case 1: cpack(0xffffffff); break;
  366.     case 2: cpack(0xff808080); break;
  367.   }
  368.  
  369.   // draw boxes around team flags that are floating free
  370.   for (j = 0; j < NUMTEAMS; j++) {
  371.     if (getTeam(Team(j)).state == FlagReady && flagView[j].visible) {
  372.       rects(flagView[j].p[0] - 6,
  373.         flagView[j].p[1] - 6,
  374.         flagView[j].p[0] + 6,
  375.         flagView[j].p[1] + 6);
  376.       rects(flagView[j].p[0] - 5,
  377.         flagView[j].p[1] - 5,
  378.         flagView[j].p[0] + 5,
  379.         flagView[j].p[1] + 5);
  380.     }
  381.   }
  382.  
  383.   }
  384.  
  385.   if (myShip->active() != ObjectActive) {
  386.     short fy = short(getheight());
  387.     short y = viewScreenSize()[1] - 4 - fh;
  388.     cpack(0xffffffff);
  389.  
  390.     if (myShip->active() == ObjectInactive) {
  391.       cmov2s(4, y);
  392.       charstr("Press space bar to begin");
  393.       y -= 2 * fy;
  394.     }
  395.     else {
  396.       cmov2s(4, y);
  397.       charstr("Press \'p\' to resume");
  398.       y -= 2 * fy;
  399.     }
  400.  
  401.     cmov2s(500, y);
  402.     charstr("Individual");
  403.     cmov2s(700, y);
  404.     charstr("Team");
  405.  
  406.     y -= fy;
  407.     cmov2s(4, y);
  408.     charstr("Player");
  409.     cmov2s(250, y);
  410.     charstr("Team");
  411.     cmov2s(350, y);
  412.     charstr("Ship");
  413.     cmov2s(450, y);
  414.     charstr("Won");
  415.     cmov2s(500, y);
  416.     charstr("Lost");
  417.     cmov2s(550, y);
  418.     charstr("Score");
  419.     cmov2s(650, y);
  420.     charstr("Won");
  421.     cmov2s(700, y);
  422.     charstr("Lost");
  423.     cmov2s(750, y);
  424.     charstr("Score");
  425.  
  426.     y -= fy >> 1;
  427.     char buf[20];
  428.     for (int i = 0; i < MAXPLAYERS; i++) {
  429.       ShipObject* s = getPlayer(i);
  430.       if (!s) continue;
  431.       y -= fy;
  432.  
  433.       cmov2s(4, y);
  434.       charstr(s->name());
  435.       cmov2s(250, y);
  436.       charstr(teamName(s->team()));
  437.       cmov2s(350, y);
  438.       charstr(shipClassName(s->shipClass()));
  439.  
  440.       sprintf(buf, "%d", s->won());
  441.       cmov2s(450, y);
  442.       charstr(buf);
  443.       sprintf(buf, "%d", s->lost());
  444.       cmov2s(500, y);
  445.       charstr(buf);
  446.       sprintf(buf, "%d", s->score());
  447.       cmov2s(550, y);
  448.       charstr(buf);
  449.  
  450.       sprintf(buf, "%d", getTeam(s->team()).won);
  451.       cmov2s(650, y);
  452.       charstr(buf);
  453.       sprintf(buf, "%d", getTeam(s->team()).lost);
  454.       cmov2s(700, y);
  455.       charstr(buf);
  456.       sprintf(buf, "%d", getTeam(s->team()).won - getTeam(s->team()).lost);
  457.       cmov2s(750, y);
  458.       charstr(buf);
  459.     }
  460.   }
  461. }
  462.  
  463. static void        hudAction(void* data, SoAction* action)
  464. {
  465.   if (action->getTypeId() == SoGLRenderAction::getClassTypeId())
  466.     drawHud(data);
  467. }
  468.  
  469. static void        setAngularVelocity(const SbVec2s& p)
  470. {
  471. // we're copying p[0] and p[1] to px and py here to avoid modifying
  472. // a const... christine
  473.   short px, py;
  474.  
  475.   px = p[0];
  476.   py = p[1];
  477.  
  478.   // handle zero motion areas in center
  479.   short cx = viewScreenSize()[0] >> 1, cy = viewScreenSize()[1] >> 1;
  480.   if (px - cx < -10) px += 10;
  481.   else if (px - cx > 10) px -= 10;
  482.   else px = cx;
  483.   if (py - cy < -10) py += 10;
  484.   else if (py - cy > 10) py -= 10;
  485.   else py = cy;
  486.  
  487.   // set target angular velocity
  488. // move px and py into pp ... christine
  489.   SbVec2s pp(px,py);
  490.  
  491.   SbVec3f avd;
  492.   getViewDirection(pp, avd);
  493.   myShip->targetAngVel(avd);
  494. }
  495.  
  496. static void        hudMouseButtonEvent(void*, SoEventCallback* ec)
  497. {
  498.   SoMouseButtonEvent* e = (SoMouseButtonEvent*)(ec->getEvent());
  499.  
  500.   if (SO_MOUSE_PRESS_EVENT(e, BUTTON1)) {
  501.     switch (currentWeapon()) {
  502.       case Laser:
  503.     myShip->fireLaser();
  504.     break;
  505.       case Missile:
  506.     if (currentTarget() == -1 || !missileLock.visible || missileLock.r!=16)
  507.       myShip->fireMissile(NULL);
  508.     else {
  509.       ShipObject* s = getTarget(currentTarget());
  510.       ShipInfo& si = s->shipInfo();
  511.       myShip->fireMissile(&(si.info));
  512.     }
  513.     break;
  514.     }
  515.   }
  516.   else if (SO_MOUSE_PRESS_EVENT(e, BUTTON3)) {
  517.     setAngularVelocity(e->getPosition());
  518.   }
  519.  
  520.   ec->setHandled();
  521. }
  522.  
  523. static void        hudLocation2Event(void*, SoEventCallback* ec)
  524. {
  525.   SoLocation2Event* e = (SoLocation2Event*)(ec->getEvent());
  526.  
  527.   // set tracking box target location
  528.   SbVec3f td;
  529.   getViewDirection(e->getPosition(), td);
  530.   myShip->trackDirection(td);
  531.  
  532.   // if right down, set new angular velocity
  533.   if (buttonPressed[RightMouseButton]) {
  534.     setAngularVelocity(e->getPosition());
  535.   }
  536.  
  537.   ec->setHandled();
  538. }
  539.  
  540. void            makeHud()
  541. {
  542.   hudColorState = 1;
  543.  
  544.   // get mouse and keyboard events in the head's up display
  545.   SoEventCallback* hudEventCallback = new SoEventCallback;
  546.   hudEventCallback->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
  547.                             hudMouseButtonEvent);
  548.   hudEventCallback->addEventCallback(SoLocation2Event::getClassTypeId(),
  549.                             hudLocation2Event);
  550.   universe->insertChild(hudEventCallback, 0);    // get 'em quick
  551.  
  552.   // add action callback to hud action routine
  553.   SoCallback* hudCallback = new SoCallback;
  554.   hudCallback->setCallback(hudAction);
  555.   universe->addChild(hudCallback);        // draw hud last
  556. }
  557.  
  558. #include <X11/Xirisw/GlxMDraw.h>
  559. static GLXconfig    hudConfig[] = { {GLX_NORMAL, GLX_STENSIZE, 1},
  560.                      {0, 0, 0} };
  561.  
  562. void            hudReset()
  563. {
  564.   // enable stencil planes in HUD
  565.   GLXconfig* c = GLXgetconfig(view->getDisplay(),
  566.             XScreenNumberOfScreen(XtScreen(view->getWidget())),
  567.             hudConfig);
  568.   XtVaSetValues(view->getWidget(), GlxNglxConfig, c, NULL);
  569.   GLXwinset(display, view->getNormalWindow());
  570.   sclear(0);
  571.  
  572.   for (int i = 0; i < SELFEXPLODENUM; i++) {
  573.     selfExplodePos[i][0] = short(viewScreenSize()[0] * (0.25+0.5*drand48())),
  574.     selfExplodePos[i][1] = short(viewScreenSize()[1] * (0.25+0.5*drand48()));
  575.   }
  576. }
  577.  
  578. void            nextHudColor()
  579. {
  580.   if (++hudColorState > 2) hudColorState = 0;
  581. }
  582.